#include "mmu.h"

#define MMU_SECDESC_AP      (3<<10)	// AP位设置为11，即所有模式下允许任何访问
#define MMU_SECDESC_DOMAIN  (0<<5)	// 选择0域
#define MMU_SECDESC_NCNB    (0<<2)	// no cache no writebuffer
#define MMU_SECDESC_WB      (3<<2)	// cache and writebuffer
#define MMU_SECDESC_TYPE    ((1<<4) | (1<<1)) // 描述符类型是段

#define MMU_SECDESC_FOR_IO   (MMU_SECDESC_AP | MMU_SECDESC_DOMAIN | MMU_SECDESC_NCNB | MMU_SECDESC_TYPE)
#define MMU_SECDESC_FOR_MEM   (MMU_SECDESC_AP | MMU_SECDESC_DOMAIN | MMU_SECDESC_WB | MMU_SECDESC_TYPE)

#define MEM		0
#define IO		1


/*  创建一级页表
 *  VA          PA          CB
 *  IROM: 异常向量表在0x0地址
 * 	0x00000000	0x00000000	11
 * 
 *  ISRAM:
 *  0xFFFF0000  0xFFFF0000  11
 * 	
 * 	DDR3:
 * 	0x42C00000	0x42C00000  11
 *  
 *  Normal I/O:
 *  0xC0000000  0xC0000000  00
 *  0xC0100000  0xC0100000  00
 *  0xC0200000  0xC0200000  00
 * 
 *  PERIPHBASE:
 *  0xF0000000  0xF0000000  00
 * 
 *  Link addr:
 *  0x70000000  0x42C00000  11
 *  
 */

void create_secdesc(unsigned int *ttb, unsigned int va, unsigned int pa, int io){
	int index;

	index = va / 0x100000;	// 确定4096个描述符中的哪一个

	if (io)
		ttb[index] = (pa & 0xfff00000) | MMU_SECDESC_FOR_IO;
	else
		ttb[index] = (pa & 0xfff00000) | MMU_SECDESC_FOR_MEM;
}

void create_page_table(){
    unsigned int *ttb = (unsigned int *)0x50000000;	// 基值选择一个未被使用的地方，4GB的一级页表占用16KB空间

	create_secdesc(ttb, 0x00000000, 0x00000000, MEM);
	create_secdesc(ttb, 0xFFFF0000, 0xFFFF0000, MEM);
	create_secdesc(ttb, 0x42C00000, 0x42C00000, MEM);
	create_secdesc(ttb, 0xC0000000, 0xC0000000, IO);
	create_secdesc(ttb, 0xC0100000, 0xC0100000, IO);
	create_secdesc(ttb, 0xC0200000, 0xC0200000, IO);
	create_secdesc(ttb, 0xF0000000, 0xF0000000, IO);
	create_secdesc(ttb, 0x70000000, 0x42C00000, MEM);

}